package com.knife.oauth.util;

import com.knife.common.constants.BaseConstants;
import com.knife.oauth.security.customer.filter.TokenConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.MultiValueMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * @author tianhao.luo@hand-china.com
 * @version 1.0
 * @date 2022年04月18日 星期一 9:32 上午
 * @description
 * @since 1.0
 */
@Slf4j
public final class ServerRequestUtils {

    public static String resolveHeader(ServerHttpRequest request, String key) {
        HttpHeaders headers = request.getHeaders();
        List<String> values = headers.get(key);
        if (values == null) {
            return null;
        }
        return values.stream()
                .filter(value -> value != null && !value.isEmpty())
                .findFirst()
                .orElseGet(() -> null);
    }

    public static String resolveParam(ServerHttpRequest request, String key) {
        MultiValueMap<String, String> params = request.getQueryParams();
        List<String> values = params.get(key);
        if (values == null) {
            return null;
        }
        return values.stream()
                .filter(value -> value != null && !value.isEmpty())
                .findFirst()
                .orElseGet(() -> null);
    }

    /**
     * @param request may be HttpServletRequest or ServerHttpRequest.
     * @param key     HeaderKey
     * @return HeaderValue，may null.
     */
    public static String getHeaderValue(Object request, String key) {
        String value = null;
        if (request instanceof HttpServletRequest) {
            value = ((HttpServletRequest) request).getHeader(key);
            if (StringUtils.isBlank(value)) {
                value = ((HttpServletRequest) request).getParameter(key);
            }
        } else if (request instanceof ServerHttpRequest) {
            value = ServerRequestUtils.resolveHeader((ServerHttpRequest) request, key);
            if (StringUtils.isBlank(value)) {
                value = ServerRequestUtils.resolveParam((ServerHttpRequest) request, key);
            }
        }
        if (StringUtils.isBlank(value)) {
            return null;
        }
        return value;
    }


    /**
     * 将json数据输出到 http输出流中
     *
     * @param response   响应信息
     * @param jsonString json字符串
     */
    public static void responseJsonString(HttpServletResponse response, String jsonString) {
        response.setContentType(BaseConstants.Http.JSON_CHARSET_UTF_8);
        byte[] bytes;
        try {
            bytes = jsonString.getBytes(BaseConstants.DEFAULT_CHARSET);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        response.setContentLength(bytes.length);
        try (OutputStream os = response.getOutputStream()) {
            os.write(bytes);
            os.flush();
            if (log.isDebugEnabled()) {
                log.debug("Send the client " + jsonString);
            }
        } catch (IOException e) {
            log.error("Exception happens.", e);
            throw new RuntimeException(e);
        }
    }


    public static String parseToken(final HttpServletRequest req) {
        String accessToken = req.getHeader(TokenConstants.HEADER_AUTH);
        if(StringUtils.isEmpty(accessToken)){
            accessToken = req.getHeader(TokenConstants.ACCESS_TOKEN);
        }
        if(org.springframework.util.StringUtils.startsWithIgnoreCase(accessToken, TokenConstants.HEADER_BEARER)) {
            accessToken = accessToken.substring(TokenConstants.HEADER_BEARER.length()+1);
        }
        return accessToken;
    }
}